<?php
namespace PsiFramework\Classes\Util\UI;

import("Classes.Util.Log.LoggerManager");
import("Classes.Util.Manager.ApplicationManager");
import("Classes.Util.UI.Printer");
import("Classes.Util.UI.Response");
import("Classes.Util.UI.Template");

use \PsiFramework\Classes\Util\Application;
use \PsiFramework\Classes\Util\Log\LoggerManager;
use \PsiFramework\Classes\Util\Manager\ApplicationManager;
use \PsiFramework\Classes\Util\UI\Printer;
use \PsiFramework\Classes\Util\UI\Response;
use \PsiFramework\Classes\Util\UI\Template;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * Classe de gestion des templates
 *
 * @package Util.UI
 */
class TemplateManager
{

    protected static /*TemplateManager*/ $_singleton ;

    protected /*array*/         $_templates ;
    protected /*array*/         $_parameters ;
    protected /*string*/        $_title ;
    protected /*array*/         $_scripts ;
    protected /*array*/         $_styles ;
    protected /*LoggerManager*/ $_loggerManager ;
    protected /*Application*/   $_application ;

    /**
     * Constructeur
     */
    public function __construct()
    {
        $this->_templates = array();
        $this->_parameters = array();
        $this->_title = '' ;
        $this->_scripts = array();
        $this->_styles = array();
        $this->_loggerManager = LoggerManager::getInstance();
        $this->_application
            = ApplicationManager::getInstance()->getApplication();
    }

    public function addParameter(/*string*/ $name, $value)
    {
        $this->_parameters[$name] = $value ;
    }

    public function getParameter(/*string*/ $name)
    {
        if (!array_key_exists($name, $this->_parameters)) {
            return null ;
        } else {
            return $this->_parameters[$name] ;
        }
    }

    /**
     * The function to add a template to display
     *
     * @param $template        the template to call
     * @param $response        the response values
     * @param $zone            the name of the template
     */
    public function addTemplate(
        /*string*/ $template,
        Response   $response,
        /*string*/ $name="main",
        /*bool*/   $ajaxCall=false
    )
    {
        $this->_templates[$name] =
            new Template($this->_application, $template, $response, $ajaxCall);
    }

    public function getTitle()
    {
        return $this->_title ;
    }

    public function setTitle(/*string*/ $title)
    {
        $this->_title = $title ;
    }

    public function addStyle(/*string*/ $value, /*string*/ $type)
    {
        if (!array_key_exists($type, $this->_styles)) {
            $this->_styles[$type] = array();
        }
        if (!in_array($value, $this->_styles[$type])) {
            $this->_styles[$type][] = $value ;
        }
    }

    public function addLitteralStyle(/*string*/ $value)
    {
        $this->addStyle($value, 'litteral');
    }

    public function addFileStyle(/*string*/ $value)
    {
        $this->addStyle($value, 'file');
    }

    public function addRemoteStyle(/*string*/ $value)
    {
        $this->addStyle($value, 'remote');
    }

    public function addScript(/*string*/ $value, /*string*/ $type)
    {
        if (!array_key_exists($type, $this->_scripts)) {
            $this->_scripts[$type] = array();
        }
        if (!in_array($value, $this->_scripts[$type])) {
            $this->_scripts[$type][] = $value ;
        }
    }

    public function addLitteralScript(/*string*/ $value)
    {
        $this->addScript($value, 'litteral');
    }

    public function addFileScript(/*string*/ $value)
    {
        $this->addScript($value, 'file');
    }

    public function addRemoteScript(/*string*/ $value)
    {
        $this->addScript($value, 'remote');
    }

    /**
     * The function to show the templates
     *
     * @param boolean $template
     * @param boolean $debug
     */
    public function show(/*boolean*/ $template=null, /*boolean*/ $debug = false)
    {
        $this->_debug = $debug ;
        $response = new Response();
        $response->setAttribute("styles", $this->_styles);
        $response->setAttribute("scripts", $this->_scripts);
        $response->setAttribute("debug", $debug);
        $response->setAttribute("logger", $this->_loggerManager);
        if ($template != null) {
            $this->_application->showTemplate($template, $response);
        } else {
            $this->displayTemplate('main', $response);
        }
    }

    /**
     * The function to display immediately a template
     *
     * @param string $template
     * @param Response $response
     */
    public static function display(
        Application $application,
        /*string*/  $template,
        Response    $response
    )
    {
        $template = new Template($application, $template, $response);
        $template->display();
    }

    /**
     * Function to display
     *
     * @param    string    $name    the name of the template
     */
    public function displayTemplate(
        /*string*/ $name,
        Response   $response=null
    )
    {
        if (array_key_exists($name, $this->_templates)) {
            $this->_templates[$name]->display($response);
        }
    }

    public function setApplication(Application $application)
    {
        $this->_application = $application ;
    }

    protected function has($array, $type)
    {
        $has = false ;
        if (array_key_exists($type, $array)) {
            if (count($array[$type])>0) {
                $has = true ;
            }
        }
        return $has ;
    }

    public function hasScriptFiles()
    {
        return $this->has($this->_scripts, 'file');
    }

    public function hasStyleFiles()
    {
        return $this->has($this->_styles, 'file');
    }

    public function hasScripts()
    {
        return $this->has($this->_scripts, 'litteral');
    }

    public function hasStyles()
    {
        return $this->has($this->_styles, 'litteral');
    }

    protected function getList($array, $type, $separator)
    {
        $list = '' ;
        if (array_key_exists($type, $array)) {
            foreach ($array[$type] as $file) {
                $list .= trim($file).$separator ;
            }
        }
        return $list ;
    }

    public function getScriptFileList()
    {
        return $this->getList($this->_scripts, 'file', ',');
    }

    public function getStyleFileList()
    {
        return $this->getList($this->_styles, 'file', ',');
    }

    public function getScriptList()
    {
        return $this->getList($this->_scripts, 'litteral', "\n");
    }

    public function getStyleList()
    {
        return $this->getList($this->_styles, 'litteral', "\n");
    }

    protected function getRemote($array)
    {
        if (array_key_exists('remote', $array)) {
            return $array['remote'] ;
        } else {
            return array();
        }
    }

    public function getRemoteScripts()
    {
        return $this->getRemote($this->_scripts);
    }

    public function getRemoteStyles()
    {
        return $this->getRemote($this->_styles);
    }

    /**
     * Function to be called instead of the constructor.
     *
     * @return TemplateManager instance
     */
    public static function getInstance()
    {

        if (self::$_singleton==null) {
            self::$_singleton = new TemplateManager();
        }

        return self::$_singleton;
    }
}
